package top.easyblog.core.support.filter;

import com.alibaba.ttl.TransmittableThreadLocal;
import com.google.common.collect.Maps;
import lombok.Data;
import top.easyblog.common.constant.TransformStatus;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.Objects;

/**
 * 事件转换上下文
 */
@Data
public class TransformContext {

    public static final String PARAM_CLIENT_IP_KEY = "CLIENT_IP";
    public static final String PARAM_UA_KEY = "UA";
    public static final String PARAM_COOKIE_KEY = "COOKIE";
    public static final String PARAM_SHORT_URL_KEY = "SL";
    public static final String PARAM_LONG_URL_KEY = "LL";
    public static final String PARAM_TARGET_LONG_URL_KEY = "RLL";
    public static final String PARAM_REMOTE_HOST_NAME_KEY = "RHN";
    public static final String PARAM_REFERER_KEY = "Referer";
    public static final String PARAM_HTTP_SERVLET_REQUEST = "HTTP_SERVLET_REQUEST";
    public static final String PARAM_HTTP_SERVLET_RESPONSE = "HTTP_SERVLET_RESPONSE";

    final ThreadLocal<Runnable> redirectAction = new TransmittableThreadLocal<>();

    private String compressionCode;

    private TransformStatus transformStatus;

    private Map<String, String> headers = Maps.newHashMap();

    private Map<String, Object> params = Maps.newHashMap();

    public static TransformContext assemble(String code, HttpServletRequest request, HttpServletResponse response) {
        TransformContext context = new TransformContext();
        context.setCompressionCode(code);
        context.setParam(TransformContext.PARAM_HTTP_SERVLET_REQUEST, request);
        context.setParam(TransformContext.PARAM_HTTP_SERVLET_RESPONSE, response);
        String ua = request.getHeader("user-agent");
        context.setHeader("user-agent", ua);
//        Enumeration<String> headerNames = request.getHeaderNames();
//        while (headerNames.hasMoreElements()) {
//            String headerName = headerNames.nextElement();
//            String headerValue = request.getHeader(headerName);
//            context.setHeader(headerName, headerValue);
//        }
        return context;
    }

    public void setTransformStatus(TransformStatus transformStatus) {
        this.transformStatus = transformStatus;
    }

    public Integer getTransformStatusValue() {
        return transformStatus.getValue();
    }

    public void addHeader(String key, String value) {
        headers.putIfAbsent(key, value);
    }

    public void setHeader(String key, String value) {
        headers.put(key, value);
    }

    public String getHeader(String key) {
        return headers.get(key);
    }

    public void releaseHeaders() {
        headers.clear();
    }

    public void addParam(String key, Object value) {
        params.putIfAbsent(key, value);
    }

    public void setParam(String key, Object value) {
        params.put(key, value);
    }

    @SuppressWarnings("unchecked")
    public <T> T getParam(String key) {
        return (T) params.get(key);
    }

    public void setRedirectAction(Runnable redirectAction) {
        this.redirectAction.set(redirectAction);
    }

    public Runnable getRedirectAction() {
        Runnable redirectAction = this.redirectAction.get();
        return Objects.nonNull(redirectAction) ? redirectAction : () -> {
        };
    }

    public void release() {
        headers.clear();
        params.clear();
    }

}
